package net.ufrog.common;

import net.ufrog.common.utils.Strings;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;

/**
 * 结果
 * 
 * @author ultrafrog
 * @version 1.0, 2012-11-30
 * @since 1.0
 */
public class Result<T> implements Serializable {

    private static final long serialVersionUID = -8508268287523566997L;

    /** 类型 */
    private Type type;

    /** 消息列表 */
    private List<String> messages;

    /** 数据 */
    private T data;

    /** 构造函数 */
    public Result() {
        messages = new LinkedList<>();
    }

    /**
     * 构造函数
     *
     * @param type 类型
     */
    public Result(Type type) {
        this();
        this.type = type;
    }

    /**
     * 构造函数
     *
     * @param type 类型
     * @param messages 消息数组
     */
    public Result(Type type, String... messages) {
        this(type);
        Stream.of(messages).forEach(this::addMessage);
    }

    /**
     * 构造函数
     *
     * @param type 类型
     * @param data 数组
     * @param messages 消息数组
     */
    public Result(Type type, T data, String... messages) {
        this(type, messages);
        this.data = data;
    }

    /**
     * 是否成功
     *
     * @return 判定结果
     */
    public boolean success() {
        return Type.SUCCESS.equals(this.type);
    }

    /**
     * 是否警告
     *
     * @return 判定结果
     */
    public boolean warning() {
        return Type.WARNING.equals(this.type);
    }

    /**
     * 是否失败
     *
     * @return 判定结果
     */
    public boolean failure() {
        return Type.FAILURE.equals(this.type);
    }

    /**
     * 读取类型
     *
     * @return 类型
     */
    public Type getType() {
        return type;
    }

    /**
     * 设置类型
     *
     * @param type 类型
     * @return 对象本身
     */
    public Result<T> setType(Type type) {
        this.type = type;
        return this;
    }

    /**
     * 读取消息列表
     *
     * @return 消息列表
     */
    public List<String> getMessages() {
        return messages;
    }

    /**
     * 读取第一条消息
     *
     * @return 第一条消息
     */
    public String getFirstMessage() {
        return messages.size() > 0 ? messages.get(0) : null;
    }

    /**
     * 添加消息
     *
     * @param message 消息
     * @return 对象本身
     */
    public Result<T> addMessage(String message) {
        if (!Strings.empty(message)) this.messages.add(message);
        return this;
    }

    /**
     * 添加消息
     *
     * @param index 索引
     * @param message 消息
     * @return 对象本身
     */
    public Result<T> addMessage(int index, String message) {
        if (!Strings.empty(message)) this.messages.add(index, message);
        return this;
    }

    /**
     * 读取数据
     *
     * @return 数据
     */
    public T getData() {
        return this.data;
    }

    /**
     * 设置数据
     *
     * @param data 数据
     * @return 对象本身
     */
    public Result<T> setData(T data) {
        this.data = data;
        return this;
    }

    /**
     * 结果对象标识<br>主要用于前端的校验
     *
     * @return 总是返回<code>TRUE</code>
     */
    public boolean isResult() {
        return true;
    }

    /**
     * 读取类型字符串
     *
     * @return 全小写字符串
     */
    public String getTypeString() {
        return type.toString().toLowerCase();
    }

    /**
     * 创建结果对象
     *
     * @param type 类型
     * @param data 数据
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> create(Type type, T data, String... messages) {
        return new Result<>(type, data, messages);
    }

    /**
     * 创建成功结果
     *
     * @param data 数据
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> success(T data, String... messages) {
        return create(Type.SUCCESS, data, messages);
    }

    /**
     * 创建成功结果
     *
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> success(String... messages) {
        return success(null, messages);
    }

    /**
     * 创建警告结果
     *
     * @param data 数据
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> warning(T data, String... messages) {
        return create(Type.WARNING, data, messages);
    }

    /**
     * 创建警告结果
     *
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> warning(String... messages) {
        return warning(null, messages);
    }

    /**
     * 创建失败结果
     *
     * @param data 数据
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> failure(T data, String... messages) {
        return create(Type.FAILURE, data, messages);
    }

    /**
     * 创建失败结果
     *
     * @param messages 消息数组
     * @return 结果对象
     */
    public static <T> Result<T> failure(String... messages) {
        return failure(null, messages);
    }

    /**
     * 类型
     *
     * @author ultrafrog
     * @version 1.0, 2012-10-18
     * @since 1.0
     */
    public enum Type {

        /** 成功 */
        SUCCESS,

        /** 警告 */
        WARNING,

        /** 失败 */
        FAILURE
    }
}
